package httpserver

import (
	"encoding/json"
	"fmt"
	"mcp-clarification-service/internal/gui"
	"mcp-clarification-service/internal/tools"
	"mcp-clarification-service/pkg/logger"
	"net/http"
	"sync"
	"time"
)

// GUIManager 接口
type GUIManager interface {
	ShowQuestions(questions []tools.Question, timeout time.Duration) ([]tools.Answer, bool, error)
	IsActive() bool
}

// Server HTTP服务器
type Server struct {
	port       int
	server     *http.Server
	guiManager GUIManager
	logger     *logger.Logger
	mu         sync.Mutex
	active     bool
}

// NewServer 创建新的HTTP服务器
func NewServer(port int, guiManager GUIManager, log *logger.Logger) *Server {
	s := &Server{
		port:       port,
		guiManager: guiManager,
		logger:     log,
	}

	mux := http.NewServeMux()
	mux.HandleFunc("/ask", s.handleAsk)
	mux.HandleFunc("/health", s.handleHealth)

	s.server = &http.Server{
		Addr:    fmt.Sprintf(":%d", port),
		Handler: mux,
	}

	return s
}

// Start 启动服务器
func (s *Server) Start() error {
	s.logger.Info("Starting HTTP server on port %d", s.port)
	return s.server.ListenAndServe()
}

// Stop 停止服务器
func (s *Server) Stop() error {
	s.logger.Info("Stopping HTTP server")
	return s.server.Close()
}

// handleAsk 处理提问请求
func (s *Server) handleAsk(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	// 检查并发
	s.mu.Lock()
	if s.active {
		s.mu.Unlock()
		http.Error(w, "Another request is in progress", http.StatusConflict)
		return
	}
	s.active = true
	s.mu.Unlock()

	defer func() {
		s.mu.Lock()
		s.active = false
		s.mu.Unlock()
	}()

	// 解析请求
	var req gui.AskRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, fmt.Sprintf("Invalid request: %v", err), http.StatusBadRequest)
		return
	}

	// 调试：打印每题的类型与选项数量（帮助定位批量多选渲染差异）
	for i, q := range req.Questions {
		optCount := len(q.Options)
		sample := ""
		if optCount > 0 {
			// 只截取前三项用于日志，避免刷屏
			max := 3
			if optCount < max {
				max = optCount
			}
			sampleSlice := q.Options[:max]
			// 保护日志：截断过长文本
			truncated := make([]string, 0, len(sampleSlice))
			for _, s := range sampleSlice {
				if len(s) > 40 {
					truncated = append(truncated, s[:40]+"…")
				} else {
					truncated = append(truncated, s)
				}
			}
			sample = fmt.Sprintf("%v", truncated)
		}
		s.logger.Debug("Q%d type=%s options=%d sample=%s", i+1, q.Type, optCount, sample)
	}

	if req.Timeout < 0 {
		req.Timeout = 0
	}
	timeout := time.Duration(req.Timeout) * time.Second

	// 显示GUI
	startTime := time.Now()
	answers, cancelled, err := s.guiManager.ShowQuestions(req.Questions, timeout)
	elapsed := time.Since(startTime)

	s.logger.Info("GUI popup took %v", elapsed)

	// 构造响应
	resp := gui.AskResponse{
		Answers:   answers,
		Cancelled: cancelled,
	}

	if err != nil {
		resp.Error = err.Error()
	}

	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	json.NewEncoder(w).Encode(resp)
}

// handleHealth 处理健康检查
func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
}
